using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using EnvDTE;
using EnvDTE80;
using System.Reflection;

namespace MouseGesturesAddIn {
  /// <summary>
  /// Desribes method which can be invoked by add-in, after user performed mouse gesture
  /// </summary>
  /// <param name="application">DTE2 application object</param>
  public delegate void MouseGestureAction(DTE2 application);

  /// <summary>
  /// Encapsulates all mousegesture actions.
  /// </summary>
  public class ActionsLibrary {

    /// <summary>
    /// Enums all mousegesture action's names in this class
    /// </summary>
    /// <returns>The array of names of actions</returns>
    public static string[] EnumAllActions() {
      ArrayList actions = new ArrayList();
      Type actionsLibraryType = typeof(ActionsLibrary);

      //find all private static methods
      MethodInfo[] methodsInfo = actionsLibraryType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Static);

      foreach(MethodInfo info in methodsInfo) {
        ParameterInfo[] parameres = info.GetParameters();

        //check whether method have correct parameters
        if(parameres.Length == 1 && parameres[0].ParameterType == typeof(DTE2)) {
          //add it's name to the  result
          actions.Add(info.Name);
        }
      }

      return (string[])actions.ToArray(typeof(string));
    }

    /// <summary>
    /// Invokes function with specified name.
    /// </summary>
    /// <param name="actionName">The name of function.</param>
    /// <param name="application">DTE2 application object</param>
    public static void InvokeAction(string actionName, DTE2 application) {
      Type actionsLibraryType = typeof(ActionsLibrary);
      //try to find method with actionName
      MethodInfo method = actionsLibraryType.GetMethod(actionName, BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Static,
        null, new Type[] {typeof(DTE2)}, null);
      
      if ( method != null ) {
        //invoke it
        method.Invoke(null, new object[] {application});
      }
    }

    #region MouseGesture Actions

    private static void CloseActiveDocument(DTE2 application) {
      if ( application.ActiveDocument != null ) {
        application.ActiveDocument.Close(vsSaveChanges.vsSaveChangesPrompt);
      }
    }

    private static void CloseAllDocuments(DTE2 application) {
      application.Documents.CloseAll(vsSaveChanges.vsSaveChangesPrompt);
    }

    private static void CloseActiveDocumentAutosave(DTE2 application) {
      if ( application.ActiveDocument != null ) {
        application.ActiveDocument.Close(vsSaveChanges.vsSaveChangesYes);
      }
    }

    private static void CloseAllDocumentsAutosave(DTE2 application) {
      application.Documents.CloseAll(vsSaveChanges.vsSaveChangesYes);
    }

    private static void ActiveDocumentSave(DTE2 application) {
      if ( application.ActiveDocument != null ) {
        if ( !application.ActiveDocument.Saved )
          application.ActiveDocument.Save(application.ActiveDocument.FullName);
      }
    }

    private static void SaveAllDocument(DTE2 application) {
      foreach ( Document doc in application.Documents ) {
        if ( !doc.Saved )
          doc.Save(doc.FullName);
      }
    }

    private static void CloseActiveWindow(DTE2 application) {
      if ( application.ActiveWindow != null ) {
        application.ActiveWindow.Close(vsSaveChanges.vsSaveChangesPrompt);
      }
    }

    private static void Quit(DTE2 application) {
      application.Quit();
    }

    private static void SolutionBuild(DTE2 application) {
      if ( application.Solution != null ) {
        application.Solution.SolutionBuild.Build(false);
      }
    }

    private static void SolutionClean(DTE2 application) {
      if ( application.Solution != null ) {
        application.Solution.SolutionBuild.Clean(false);
      }
    }

    private static void SolutionDebug(DTE2 application) {
      if ( application.Solution != null ) {
        application.Solution.SolutionBuild.Debug();
      }
    }

    private static void SolutionRun(DTE2 application) {
      if ( application.Solution != null ) {
        application.Solution.SolutionBuild.Run();
      }
    }

    private static void SolutionCloseAutosave(DTE2 application) {
      if ( application.Solution != null ) {
        application.Solution.Close(true);
      }
    }

    private static void SolutionClose(DTE2 application) {
      if ( application.Solution != null ) {
        application.Solution.Close(false);
      }
    }

    private static void DebuggerRunToCursor(DTE2 application) {
      if ( application.Debugger != null ) {
        application.Debugger.RunToCursor(false);
      }
    }

    private static void DebuggerGo(DTE2 application) {
      if ( application.Debugger != null ) {
        application.Debugger.Go(false);
      }
    }

    private static void DebuggerStepInto(DTE2 application) {
      if ( application.Debugger != null ) {
        application.Debugger.StepInto(false);
      }
    }

    private static void DebuggerStepOut(DTE2 application) {
      if ( application.Debugger != null ) {
        application.Debugger.StepOut(false);
      }
    }

    private static void DebuggerStepOver(DTE2 application) {
      if ( application.Debugger != null ) {
        application.Debugger.StepOver(false);
      }
    }

    private static void DebuggerStop(DTE2 application) {
      if ( application.Debugger != null ) {
        application.Debugger.Stop(false);
      }
    }
    
    #endregion

  }
}
